/**
 * Copyright (c) 2011 The MITRE Corporation. All rights reserved.
 *
 * NOTICE
 * This software was produced for the U. S. Government
 * under Contract No. FA8721-11-C-0001, and is
 * subject to the Rights in Noncommercial Computer Software
 * and Noncommercial Computer Software Documentation Clause
 * (DFARS) 252.227-7014 (JUN 1995)
 */
package org.mitre.edxl.lib;

import java.util.ArrayList;
import java.util.List;

/**
 * Container element for specific messages.
 *
 * @author Danny Gagne
 * @author Rob Gustafson
 * @author Brian Wilkins
 * @author Greg Kern
 */
public class ContentObject {
  private String contentDescription;
  private String incidentID;
  private String incidentDescription;
  private String confidentiality;

  private List<EDXLStringList> contentKeyword;
  private List<EDXLStringList> originatorRole;
  private List<EDXLStringList> consumerRole;

  private NonXMLContent nonXMLContent;
  private XMLContent xmlContent;

  private List<String> other;

  /**
   * Adds a Content Keyword to the Content Keyword list.
   *
   * @param val The new Content Keyword to be added to the list.
   */
  public void addKeyword(EDXLStringList val) {
    this.contentKeyword = addToList(this.contentKeyword, val);
  }

  /**
   * Adds a Originator Role to the Originator Role.
   *
   * @param val The new OriginatorRole to be added to the list.
   */
  public void addOriginatorRole(EDXLStringList val) {
    this.originatorRole = addToList(this.originatorRole, val);
  }

  /**
   * Adds a Consumer Role to the Consumer Role list.
   *
   * @param val The new Consumer Role to be added to the list.
   */
  public void addConsumerRole(EDXLStringList val) {
    this.consumerRole = addToList(this.consumerRole, val);
  }

  /**
   * Adds a XML segment to the Generic XML segment list.
   *
   * @param val The new Generic XML segment to be added to the list.
   */
  public void addOtherXML(String val) {
    this.other = addToList(this.other, val);
  }

  /**
   * Utility method that take in a list, initializes the list if needed,
   * added the need item to the list, and returns the updated list.
   *
   * @param list The list to which the new value will be added to.
   * @param val The new value to be added to the list.
   * @return Updated version of the original list containing the new value.
   */
  private <T> List<T> addToList(List<T> list, T val) {
    if (list == null) {
      list = new ArrayList<T>();
    }
    list.add(val);

    return list;
  }

  /**
   * Returns a XML representation of the ContentObject object.
   *
   * @return A String of the XML representation of the ContentObject object.
   */
  public String toXML() {
    StringBuilder sb = new StringBuilder();

    sb.append(addStringElement(this.contentDescription, "contentDescription"));
    sb.append(addStringListElement(this.contentKeyword, "contentKeyword"));
    sb.append(addStringElement(this.incidentID, "incidentID"));
    sb.append(addStringElement(this.incidentDescription, "incidentDescription"));
    sb.append(addStringListElement(this.originatorRole, "originatorRole"));
    sb.append(addStringListElement(this.consumerRole, "consumerRole"));
    sb.append(addStringElement(this.confidentiality, "confidentiality"));

    if (this.nonXMLContent != null) {
      sb.append("<nonXMLContent>");
      sb.append(this.nonXMLContent.toXML());
      sb.append("</nonXMLContent>");
    }

    if (this.xmlContent != null) {
      sb.append("<xmlContent>");
      sb.append(this.xmlContent.toXML());
      sb.append("</xmlContent>");
    }

    if (this.other != null) {
      for (String val : this.other) {
        sb.append(val);
      }
    }

    return sb.toString();
  }

  /**
   * Creates a String of XML elements with the given name, one for each
   * value in the list.
   *
   * @param valList The list of values to add XML element for.
   * @param elementName The name that should be given to the XML element.
   * @return The String containing the a series of XML elements.
   */
  private String addStringListElement(List<EDXLStringList> valList,
      String elementName) {
    String temp = "";

    if (valList != null) {
      for (EDXLStringList val : valList) {
        temp += addStringElement(val.toXML(), elementName);
      }
    }
    return temp;
  }

  /**
   * Creates a String of a XML element with the given name for the given value.
   *
   * @param val The value for the XML element.
   * @param elementName The name that should be given to the XML element.
   * @return The String of the XML element.
   */
  private String addStringElement(String val, String elementName) {
    String temp = "";

    if (val != null) {
      temp += "<" + elementName + ">" + val + "</" + elementName + ">";
    }

    return temp;
  }

  /**
   * Get the value for the Content Description.
   *
   * @return The String value of the Content Description.
   */
  public String getContentDescription() {
    return this.contentDescription;
  }

  /**
   * Set the Content Description value.
   *
   * @param val The value to set the Content Description to.
   */
  public void setContentDescription(String val) {
    this.contentDescription = val;
  }

  /**
   * Get the value for the Incident Identifier.
   *
   * @return The String value of the Incident Identifier.
   */
  public String getIncidentID() {
    return this.incidentID;
  }

  /**
   * Set the Incident Identifier value.
   *
   * @param val The value to set the Incident Identifier to.
   */
  public void setIncidentID(String val) {
    this.incidentID = val;
  }

  /**
   * Get the value for the Incident Description.
   *
   * @return The String value of the Incident Description.
   */
  public String getIncidentDescription() {
    return this.incidentDescription;
  }

  /**
   * Set the Incident Description value.
   *
   * @param val The value to set the Incident Description to.
   */
  public void setIncidentDescription(String val) {
    this.incidentDescription = val;
  }

  /**
   * Get the value for the Confidentiality.
   *
   * @return The String value of the Confidentiality.
   */
  public String getConfidentiality() {
    return this.confidentiality;
  }

  /**
   * Set the Confidentiality value.
   *
   * @param val The value to set the Confidentiality to.
   */
  public void setConfidentiality(String val) {
    this.confidentiality = val;
  }

  /**
   * Get the list of the Content Keyword values.
   *
   * @return The list of the Content Keyword values.
   */
  public List<EDXLStringList> getContentKeyword() {
    return this.contentKeyword;
  }

  /**
   * Set the list of the Content Keyword values.
   *
   * @param val The list to set the Content Keyword values to.
   */
  public void setContentKeyword(List<EDXLStringList> val) {
    this.contentKeyword = val;
  }

  /**
   * Get the list of the Originator Role values.
   *
   * @return The list of the Originator Role values.
   */
  public List<EDXLStringList> getOriginatorRole() {
    return this.originatorRole;
  }

  /**
   * Set the list of the Originator Role values.
   *
   * @param val The list to set the Originator Role values to.
   */
  public void setOrginatorRole(List<EDXLStringList> val) {
    this.originatorRole = val;
  }

  /**
   * Get the list of the Consumer Role values.
   *
   * @return The list of the Consumer Role values..
   */
  public List<EDXLStringList> getConsumerRole() {
    return this.consumerRole;
  }

  /**
   * Set the list of the Consumer Role values.
   *
   * @param val The list to set the Consumer Role values to.
   */
  public void setConsumerRole(List<EDXLStringList> val) {
    this.consumerRole = val;
  }

  /**
   * Get the value for the Non XML Content.
   *
   * @return The NonXMLContent object of the Non XML Content.
   */
  public NonXMLContent getNonXMLContent() {
    return this.nonXMLContent;
  }

  /**
   * Set the Non XML Content value.
   *
   * @param val The value to set the Non XML Content to.
   */
  public void setNonXMLContent(NonXMLContent val) {
    this.nonXMLContent = val;
  }

  /**
   * Get the value for the XML Content.
   *
   * @return The XMLContent object of the XML Content.
   */
  public XMLContent getXMLContent() {
    return this.xmlContent;
  }

  /**
   * Set the XML Content value.
   *
   * @param val The value to set the XML Content to.
   */
  public void setXMLContent(XMLContent val) {
    this.xmlContent = val;
  }
}
